package com.handydata.antifraud.rule;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import com.alibaba.fastjson.JSON;
import com.bstek.urule.model.flow.FlowNode;
import com.bstek.urule.model.flow.FlowNodeType;
import com.bstek.urule.model.flow.NodeEvent;
import com.bstek.urule.model.flow.ins.FlowContext;
import com.bstek.urule.model.flow.ins.ProcessInstance;
import com.handydata.antifraud.bo.decisionexecrecord.DecisionExecRecordReqBO;
import com.handydata.antifraud.service.DecisionExecRecordService;
import com.handydata.antifraud.to.RiskInputTO;
import com.handydata.antifraud.to.RiskMiddleTO;

@Slf4j
@Component
public class MyNodeEvent implements NodeEvent {
    @Autowired
    private DecisionExecRecordService decisionExecRecordService;
    @Override
    public void enter(FlowNode flowNode, ProcessInstance processInstance, FlowContext flowContext) {

        try{
            RiskInputTO riskInputTO = RuleEngineVarCollector.collect(flowContext, RiskInputTO.class).get();
            RiskMiddleTO riskMiddleTO = RuleEngineVarCollector.collect(flowContext, RiskMiddleTO.class).get();
            riskMiddleTO.getRuleStartTimes().put(flowNode.getName(),System.currentTimeMillis());
            log.info("开始执行规则 name:"+flowNode.getName()+"orderid"+riskInputTO.getOrderId());
        }catch (Exception ex){
            log.error("node 开始执行规则出错{}",flowNode.getName(),ex);

        }
    }

    @Override
    public void leave(FlowNode flowNode, ProcessInstance processInstance, FlowContext flowContext) {

       try {
           if(flowNode!=null&& FlowNodeType.Rule==flowNode.getType()) {
               RiskInputTO riskInputTO = RuleEngineVarCollector.collect(flowContext, RiskInputTO.class).get();
               RiskMiddleTO riskMiddleTO = RuleEngineVarCollector.collect(flowContext, RiskMiddleTO.class).get();
               String name = flowNode.getName();
               log.info("规则执行完成 name:"+flowNode.getName()+"orderid"+riskInputTO.getOrderId());
//                 String[] strs=flowNode.getName().split("|");
//                 int risk=1;
//                 if(strs.length>1){
//                     risk=getInt(strs[1]);
//                 }
//                  List<Connection> cons=flowNode.getConnections();
//                  if(cons.size()>0){
//                      String parent=cons.get(0).getToName();
//                      Integer val=riskMiddleTO.getRuleTypRiskCount().get(parent);
//                      if(val==null){
//                          riskMiddleTO.getRuleTypRiskCount().put(parent,risk);
//                      }else {
//                          riskMiddleTO.getRuleTypRiskCount().put(parent,val+risk);
//                      }
//                  }
               CompletableFuture.runAsync(()->insertRuleLog(name,riskInputTO,riskMiddleTO));
               //insertRuleLog(name,riskInputTO,riskMiddleTO);
           }
       }catch (Exception ex){
           log.error("node 退出事件出错{}",flowNode.getName(),ex);
       }

    }

	private void insertRuleLog(String ruleId,RiskInputTO riskInputTO, RiskMiddleTO riskMiddleTO){
        try{
            Map<String, Object> params=new HashMap<String, Object>();
            String str=(String)RuleExecLog.ruleConfigMap.get(ruleId);
            //log.info("start log {}",ruleId);

            if(str!=null&&str.length()>0){
                String[] inputProps=str.split(",");
				for (String prop : inputProps) {
					Object val = null;
					Field f = ReflectionUtils.findField(riskInputTO.getClass(), prop);
					if (f != null) {
						f.setAccessible(true);
						val = ReflectionUtils.getField(f, riskInputTO);
					} else {
						f = ReflectionUtils.findField(riskMiddleTO.getClass(), prop);
						if (f != null) {
							f.setAccessible(true);
							val = ReflectionUtils.getField(f, riskMiddleTO);
						}
					}
					if (val != null && !"null".equals(val))
						params.put(prop, val);
				}
                DecisionExecRecordReqBO bo=new DecisionExecRecordReqBO();
                bo.setOrderId(riskInputTO.getOrderId());
                bo.setNodeName(ruleId);
                bo.setInput(JSON.toJSONString(params));
                bo.setNodeType("1");

                String declares="";
                Long start=riskMiddleTO.getRuleStartTimes().get(ruleId);
                bo.setCreateTime(new Date(start));
                bo.setUpdateTime(new Date());
                bo.setElapsed(Long.valueOf(System.currentTimeMillis()-start).intValue());
                String[] IdSegs=ruleId.replace("XIAOSHI","XIAO_SHI").
                        replace("NETWORK","NET_WORK").split("_");
                if(IdSegs.length>1){
                    for(String seg:IdSegs){
                        declares+=(seg.charAt(0)+"").toUpperCase()+seg.substring(1).toLowerCase();
                    }
                    declares=(declares.charAt(0)+"").toLowerCase()+declares.substring(1)+"Hit";

                    Field f= ReflectionUtils.findField(riskMiddleTO.getClass(),declares);
                    if(f!=null) {
                        f.setAccessible(true);
                        bo.setOutput(String.valueOf(ReflectionUtils.getField(f, riskMiddleTO)));
                    }
                }
                decisionExecRecordService.createDecisionExecRecord(bo);
            }
        }catch (Exception ex){
            log.error("记录规则日志出错{}",ruleId,ex);
        }
    }

}

